<!DOCTYPE html>
<html>
<head>
<title>Physics Diagram of a Wave on a String</title>
</head>
<body>

<canvas id="myCanvas" width="500" height="300" style="border: 1px solid #ccc;"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style and Configuration ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';

    const x0 = 280; // x-coordinate of the origin (mass m)
    const y0 = 150; // y-coordinate of the origin (string position)

    // --- Helper function to draw an arrow ---
    function drawArrow(fromx, fromy, tox, toy) {
        const headlen = 10; // length of head in pixels
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        // Arrowhead lines
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }

    // --- Drawing the components ---

    // 1. Draw Axes
    // Y-axis
    drawArrow(x0, 250, x0, 40);
    // Right part of X-axis (which also represents the string to the right of the mass)
    drawArrow(x0, y0, 460, y0);
    
    // 2. Draw Left part of the string with the wave packet (zigzag)
    ctx.beginPath();
    ctx.moveTo(50, y0); // Start of the string on the left
    let currentX = 160;
    ctx.lineTo(currentX, y0); // Straight segment before the packet

    // Parameters for the zigzag shape
    const num_peaks = 4;
    const peak_width = 15;
    const peak_height = 15;
    
    // Loop to create the zigzag pattern
    for (let i = 0; i < num_peaks; i++) {
        // Upward stroke for the peak
        ctx.lineTo(currentX + peak_width, y0 - peak_height);
        currentX += peak_width;
        // Downward stroke for the valley (not drawn after the last peak)
        if (i < num_peaks - 1) { 
            ctx.lineTo(currentX + peak_width, y0 + peak_height);
            currentX += peak_width;
        }
    }
    // Connect the end of the zigzag packet to the mass at the origin
    ctx.lineTo(x0, y0);
    ctx.stroke();

    // 3. Draw Propagation Arrow
    drawArrow(180, y0 - 40, 230, y0 - 40);
    
    // 4. Draw Mass 'm'
    ctx.beginPath();
    ctx.arc(x0, y0, 4.5, 0, 2 * Math.PI);
    ctx.fill();

    // 5. Draw Labels
    ctx.font = 'italic 18px serif';
    ctx.fillText('y', x0 + 10, 45);
    ctx.fillText('x', 470, y0 + 6);
    ctx.fillText('m', x0 - 5, y0 + 25);
    
    // 6. Draw Figure Caption
    ctx.font = 'bold 16px serif';
    ctx.textAlign = 'center';
    ctx.fillText('Fig. 1.218.', canvas.width / 2, 280);

</script>

</body>
</html>